package edu.hit.crawler.util;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;

import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class LockAccessFile {
	
	private static final String keyName = "org.work.incrementcrawler.ParsedNewURLs";
	
	public static void WriteToXML(FileSystem fs, Path filePath, String keyName, boolean value) {
		XMLEncoder xmlEncoder = null;
		FileOutputStream outStream = null;
		FileLock lock = null;
		FSDataOutputStream fsd = null;
		
		try {
			
			if (fs.exists(filePath)) {
				fs.delete(filePath, true);			
			} 
			fsd = fs.create(filePath);	

			try {
				fsd.sync();
				System.out.println("Get the Lock!");

				xmlEncoder = new XMLEncoder(outStream);

				Hashtable ht = new Hashtable<String, Boolean>();
				ht.put(keyName, value);
				
				xmlEncoder.writeObject(ht);
				xmlEncoder.flush();					
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		} catch (IOException e) {
			System.out.println(e.getMessage());
		} finally {
			if (null != lock) {
				try {
					System.out.println("Release The Lock" + new Date().toString());
					lock.release();
				} catch (IOException e) {
					System.out.println(e.getMessage());
				}
			}
			
			if (xmlEncoder != null) {
				try {
					xmlEncoder.close();
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}

			if (outStream != null) {
				try {
					outStream.close();
				} catch (IOException e) {
					System.out.println(e.getMessage());
				}
			}
		}
	}
	
	public static boolean ReadFromXML(String fileName, String keyName) {
		XMLDecoder xmlDecoder = null;
		FileInputStream inStream = null;
		//FileLock lock = null;
		boolean value = false;
		
		try {
			
			File pFile = new File(fileName);						

			inStream = new FileInputStream(pFile);
			//FileChannel channel = inStream.getChannel();

			try {
				//lock = channel.lock();
				//System.out.println("Get the Lock!");

				xmlDecoder = new XMLDecoder(inStream);

				// 从xml解析对象中 凡序列话得到 内存对象（集合）
				Object obj = null;

				obj = xmlDecoder.readObject();
				
				Hashtable ht = (Hashtable)obj;
				
				value = (Boolean)ht.get(keyName);				
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
		} catch (IOException e) {
			System.out.println(e.getMessage());
		} finally {
			/*if (null != lock) {
				try {
					System.out.println("Release The Lock" + new Date().toString());
					lock.release();
				} catch (IOException e) {
					System.out.println(e.getMessage());
				}
			}*/
			
			if (xmlDecoder != null) {
				try {
					xmlDecoder.close();
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}

			if (inStream != null) {
				try {
					inStream.close();
				} catch (IOException e) {
					System.out.println(e.getMessage());
				}
			}
		}
		
		return value;
	}
	
	public static void ReLoad() {
		//WriteToXML(keyName, true);
	}
	
	public static void ReLoad(String fileName, String keyName) {
		//WriteToXML(fileName, keyName, true);
	}
	
	public static boolean getStatus(String fileName) {
		return ReadFromXML(fileName, keyName);
	}
	
	public static boolean getStatus(String fileName, String keyName) {
		return ReadFromXML(fileName, keyName);
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String fileName = "c:\\tmp.xml";
		
		//WriteToXML(fileName, keyName, false);
		
		System.out.println(ReadFromXML(fileName, keyName));
		
		/*
		// 文件锁所在文件
		File lockFile = new File("c:\\tmp.xml");
		
		FileOutputStream outStream = null;
		FileLock lock = null;

		try {
			outStream = new FileOutputStream(lockFile);
			FileChannel channel = outStream.getChannel();

			try {

				// 方法一
				lock = channel.lock();
				System.out.println("Get the Lock!");
				// do something...
				
				HashMap hm = new HashMap();
				hm.put("org.work.tag", false);
				
				XMLEncoder xmlEncoder = new XMLEncoder(outStream);
				// 利用xml对象输出类输出对象到xml文件
				xmlEncoder.writeObject(hm);
				xmlEncoder.flush();
				// 关闭输出对象
				//xmlEncoder.close();

				// 方法二
				// lock = channel.tryLock();
				// if(lock != null){
				// do something..
				// }
			} catch (IOException e) {
				//e.printStackTrace();
				System.out.println(e.getMessage());
			}
		} catch (FileNotFoundException e) {
			//e.printStackTrace();
			System.out.println(e.getMessage());
		} finally {
			if (null != lock) {
				try {
					System.out.println("Release The Lock" + new Date().toString());
					lock.release();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (outStream != null) {
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}*/	
	}
}
